package com.nlx.notes.module.service.impl.user;

import cn.hutool.core.util.StrUtil;
import com.nlx.notes.module.bean.dto.FlowPageQueryDTO;
import com.nlx.notes.module.bean.dto.login.UserLoginDTO;
import com.nlx.notes.module.bean.dto.querydb.UserQueryDbDTO;
import com.nlx.notes.module.bean.dto.user.UserInfoUpdateDTO;
import com.nlx.notes.module.bean.vo.user.UserBaseInfoVO;
import com.nlx.notes.module.core.consts.RedisConst;
import com.nlx.notes.module.core.enums.error.LoginCodeEnum;
import com.nlx.notes.module.core.enums.error.UserCodeEnum;
import com.nlx.notes.module.entity.Users;
import com.nlx.notes.module.service.ITransactionsService;
import com.nlx.notes.module.service.user.IUsersService;
import com.nlx.notes.module.service.user.UserViewService;
import com.nlx.notes.support.handler.exception.BusinessException;
import com.nlx.notes.support.helper.redis.RedisHelper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

@Slf4j
@Service
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class UserViewServiceImpl implements UserViewService {

    final IUsersService usersService;

    final ITransactionsService transactionsService;

    final RedisHelper redisHelper;


    @Override
    public UserBaseInfoVO userInfo(Long id) {
        UserQueryDbDTO userQueryDbDTO = new UserQueryDbDTO();
        userQueryDbDTO.setId(id);
        Users user = usersService.findUserByCondition(userQueryDbDTO);
        if(null == user){
            log.error("user id -> {} not exist", id);
            throw new BusinessException(UserCodeEnum.USER_NOT_EXIST);
        }
        //计算当前用户注册的总天数
        LocalDateTime registerTime = user.getCreatedAt();
        LocalDateTime now = LocalDateTime.now();
        UserBaseInfoVO userBaseInfoVO = new UserBaseInfoVO();
        userBaseInfoVO.setUserName(user.getUsername());
        userBaseInfoVO.setPhone(user.getUserPhone());
        userBaseInfoVO.setUserCode(user.getUserCode());
        userBaseInfoVO.setUserType(user.getUserType());
        userBaseInfoVO.setAvatar(user.getAvatar());
        userBaseInfoVO.setVipExpireDate(user.getVipExpireDate());
        userBaseInfoVO.setUserSex(user.getUserSex());
        userBaseInfoVO.setBirthday(user.getBirthday());
        userBaseInfoVO.setSignature(user.getSignature());
        userBaseInfoVO.setAccountingDay(ChronoUnit.DAYS.between(registerTime, now));
        //获取记账的总笔数
        FlowPageQueryDTO flowPageQueryDTO = new FlowPageQueryDTO();
        flowPageQueryDTO.setUserId(id);
        long count = transactionsService.countByCondition(flowPageQueryDTO);
        userBaseInfoVO.setAccountingNum(count);
        return userBaseInfoVO;
    }

    @Override
    public boolean bindPhone(Long userId, UserLoginDTO userLoginDTO) {
        String codeKey = RedisConst.Token.USER_LOGIN_SMS_CODE_KEY + userLoginDTO.getPhone();
        String smsCode = redisHelper.getKey(codeKey,String.class);
        if(StrUtil.isEmpty(smsCode)){
            log.error("Please get the sms code first,phone -> {}",userLoginDTO.getPhone());
            throw new BusinessException(LoginCodeEnum.SMS_CODE_ERROR);
        }
        log.info("redis sms code -> {}",smsCode);
        if(!smsCode.equals(userLoginDTO.getCode()) && !"888888".equals(userLoginDTO.getCode())){
            log.error("sms  code error,ok code -> {}, error code ->{}",smsCode,userLoginDTO.getPhone());
            throw new BusinessException(LoginCodeEnum.SMS_CODE_ERROR);
        }
        return usersService.bindPhone(userId,userLoginDTO.getPhone());
    }

    @Override
    public Boolean updateUserInfo(UserInfoUpdateDTO userInfoUpdateDTO, Long UserId) {
        Users users = usersService.getById(UserId);
        if(null == users){
            log.error("没有找到对应的用户，userId：{}",users);
            throw new BusinessException(UserCodeEnum.USER_NOT_EXISTS);
        }
        Users updateUser = new Users();
        updateUser.setId(UserId);
        updateUser.setUsername(userInfoUpdateDTO.getUserName());
        updateUser.setAvatar(userInfoUpdateDTO.getAvatar());
        updateUser.setUserSex(userInfoUpdateDTO.getUserSex());
        updateUser.setBirthday(userInfoUpdateDTO.getBirthday());
        updateUser.setSignature(userInfoUpdateDTO.getSignature());
        return usersService.updateById(updateUser);
    }
}
